﻿using AudioStudio;
using AudioStudio.Components;
using Gameplay.PVE.Utils;
using System;
using System.Collections.Generic;
using com.yoozoo.gta.Gameplay.RTS;
using Unity.Collections;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Profiling;
using XLua;
using Yoozoo.Gameplay;
using Yoozoo.Gameplay.RTS;
using Yoozoo.Gameplay.RTS.Proto;
using Yoozoo.Gta.Common;
using Random = UnityEngine.Random;
using WorldMapBase;


/// <summary>
/// 行军实体，控制Hud 方阵行为等
/// </summary>
public class MarchEntity
{
    public float flyTextTimeOffset = 0;
    public enum SquareAction
    {
        Stay = 1,
        March = 2,
        Attack = 3,
    }

    public List<BattleFormationCfg> formationCfgs => _marchSquare.formationCfgs;
    private MarchSquare _marchSquare;
    private float _deadAlphaTime;
    private float _deadCheckSoldier;

    private float _deadDuration;
    private float _deadHudShowTime = -1f;
    private float _deadRotateTime;
    private float _deadStartTime = -1f;

    public bool isMonster = false;

    [BlackList]
    public bool IsSelected = false;

    public int LineId;
    private SquareAction _action = SquareAction.Stay;

    [BlackList]
    public MarchInfo MarchInfo;
    [BlackList]
    public HudBase Hud;
    [BlackList]
    public HudBase copyHud;

    private bool m_isInBattle = false;

    public RtsServerInfo RtsServerInfo;
    public bool IsInBattle
    {
        get { return m_isInBattle; }
        set
        {
            if (ArmyManager.IsDebug)
            {
                Debug.LogError(Tid+" MarchEntity.IsInBattle = " + value);
            }
            m_isInBattle = value;
        }
    }

    public MarchManager MarchManager;
    [BlackList]
    /// 创建MarchEntity的时候传进来的
    public EClientMarchType ClientMarchType;

    [BlackList]
    public MarchMono Mono;

    [BlackList] public AudioEmitter3D AudioEmitter;

    [BlackList]
    public float Radius = 0.3f;

    public long Tid => MarchInfo.Uid;
    [BlackList]
    public Transform Transform => Mono.transform;
    [BlackList]
    public bool IsWaitDelete = false;


    [BlackList]
    public bool isServerPosChange = false;

    [BlackList]
    public DirectionEffectType DirectionEffectType;
    [BlackList]
    public int DirectionEffectIndex;
    [BlackList]
    public GameObject DirectionEffectObj;

    #region CarSkillHit

    [BlackList] public SkillHit m_CarSkillHit;
    #endregion

    [BlackList]
    public bool isArenaMarch;

    [BlackList]
    public bool isArenaMarchInDeck;

    [BlackList] public bool isExpeditionMarch;
    [BlackList] public bool isExpeditionMarchInDeck;
    [BlackList] public bool isExpeditionMarchMoving;
    [BlackList] public bool isTruckFighting;
    private bool m_bIsCargoTruckFakeMarch = false;
    
    [BlackList] public int ClientCreateMarch;// 客户端模拟的部队 用于模拟货车攻击部队 1 列车攻击部队 2 列车防守部队 3
    [BlackList] public bool isTrainFighting;
    [BlackList] public bool bIsCargoTruckFakeMarch { get { return m_bIsCargoTruckFakeMarch; } set { m_bIsCargoTruckFakeMarch = value; if (value) { Mono.SetColliderRadius(0); } } }

    #region Context

    private int m_curRageHeroIdx;

    [BlackList]
    public int CurRageHeroIdx
    {
        get
        {
            return m_curRageHeroIdx;
        }
        set
        {
            if (m_curRageHeroIdx != value)
            {
                m_curRageHeroIdx = value;
                OnCurRageHeroIdxChange();
            }else m_curRageHeroIdx = value;
        }
    }

    /// <summary>
    /// 当前部队的最大怒气
    /// </summary>
    [BlackList]
    public int CurHeroRageMax
    {
        get
        {
            if (MarchInfo != null && MarchInfo.HeroRageList != null && MarchInfo.HeroRageList.Count > 0)
            {
                if (MarchInfo.HeroRageList.Count >= CurRageHeroIdx && CurRageHeroIdx >= 0)
                {
                    return MarchInfo.HeroRageList[CurRageHeroIdx];
                }

                if (MarchInfo.HeroRageList.Count > 0)
                {
                    return MarchInfo.HeroRageList[0];
                }
            }
            //其他种类英雄怒气上限的获取策略
            if (ClientMarchType == EClientMarchType.Monster && MarchInfo.HeroList.Count > 0)
            {
                int cuRageHeroIdx = 0;
                if (MarchInfo.HeroList.Count > CurRageHeroIdx && CurRageHeroIdx > 0)
                {
                    cuRageHeroIdx = CurRageHeroIdx;
                }
                hero_monster monsterCfg = ArmyManager.Instance.ResourceManager.GetHeroMonsterConig(MarchInfo.HeroList[cuRageHeroIdx]);
                if (monsterCfg != null)
                {
                    int skillId = monsterCfg.skill_active[0];
                    if (skillId > 0)
                    {
                        int skillLv = monsterCfg.skill_active[1];
                        THeroSkill skillCfg = ArmyManager.Instance.ResourceManager.GetHeroSkillConfig(skillId, skillLv);
                        if (skillCfg.mana > 0)
                        {
                            return skillCfg.mana;
                        }
                    }
                }
            }
            return MarchInfo.MaxRage;
        }
    }
    #endregion

    public MarchEntity()
    {
        MarchInfo = new MarchInfo(this);
    }

    public Vector3 Forward => MarchInfo.CurrentForward;

    public Vector3 Position
    {
        get
        {
            if (ClientMarchType == EClientMarchType.MapPoliceOffice)
            {
                return MarchInfo.Coordinate;
            }
            else if (isTrainDefenceMarch())
            {
                return GetTruckAttackerPosition();
            }
            else
            {
                return MarchInfo.Position;
            }
        }
    }

    public Vector3 EndPosition => MarchInfo.EndPosition;

    public Vector3 AttackForward
    {
        get
        {
            var battleTarget = GetBattleTarget();
            if (battleTarget != null)
            {
                return  Position - battleTarget.Position;
            }
            else
            {
                return Forward;
            }
        }
    }
    public int Team => MarchInfo.Team;
    [BlackList]
    public MarchSquare EnemyTarget;

    private EMarchStatus _cacheMarchStatue;

    #region 与当前物体相关的音效控制-参数部分
    /// <summary>
    /// 当前正在播放的移动音效
    /// </summary>
    private string currentMoveSound = "";
    //当前是否正在播放怪物的战斗背景音效(是的话,如果dispose之前还没有停止,需要强制停止)
    public bool isMonsterBattleSoundDirty = false;
    #endregion

    public List<SoldierLocation> formationPos => _marchSquare?.formationPos;
    private float lastUpdateFightForwardTime;
    public bool fixedSoldierID;
    private bool modelTotalNumChange;
    public List<Transform> forwardObjList = new List<Transform>(3);
    public bool Visible = false;

//    public TroopMarch troopServerData;
//    public RtsMapMonster monsterServerData;
    public bool InitPos = false;

    public bool isFakeParent = false;
    public bool isFakeChild;
    public List<MarchEntity> childEntities;

    private float delayRemoveTime = -1;
    /// <summary>
    /// 部队的类型（服务器传的）
    /// </summary>
    public TargetCoordinateType TargetCoordinateType;
    public void Initialize(long tid,int team,EClientMarchType clientMarchType,TargetCoordinateType targetCoordinateType)
    {
        isReadyToHide = false;
        isMarchVisibleInLod = true;
        isBeforeDispose = false;
        IsWaitDelete = false;
        ClientMarchType = clientMarchType;
        forwardObjList.Clear();
        MarchInfo.Initialize(tid,team);
        isMonster = false;
        isMonsterBattleSoundDirty = false;
        InitPos = false;
        needChangeSquareStateByMarchType = false;
        //Mono.SetTeam(team);
        Mono.SetColliderRadius(team, targetCoordinateType);
        TargetCoordinateType = targetCoordinateType;
        m_curRageHeroIdx = 0;
    }

    public void AddForwardObj(Transform trans)
    {
        forwardObjList?.Add(trans);
    }

    public void RemoveForwardObj(Transform trans)
    {
        forwardObjList?.Remove(trans);
    }
    [BlackList]
    public void SetParent(Transform parent)
    {
        Mono.gameObject.transform.SetParent(parent);
    }


    public GameObject GetGameObject()
    {
        return Mono.gameObject;
    }

    public GameObject GetAudioEmiterObject()
    {
        return Mono?.marchAudioEmitter?.gameObject;
    }
//TODO: 这个其实是行军状态
    public int GetMarchType()
    {
        return (int)MarchInfo.ClientMarchStatue;
    }

    public void SetTeam(int team)
    {
        var oldTeam = MarchInfo.Team;
        if (oldTeam!=team)
        {
            MarchInfo.SetTeam(team);
            SetDrawLineColor();
            //_marchSquare?.SetTeamColor(team);
            Hud?.SetTeam(team);
            //Mono.SetTeam(team);
            Mono.SetColliderRadius(team, TargetCoordinateType);
        }
    }

    public void SetDrawLineColor()
    {
        if (LineId > 0)
        {
            DrawLineTool.GetInstance().ChangeLineColor(LineId, MarchInfo.Team);
        }
    }
    // 设置是否可以点击
    public void SetTouchable(bool value)
    {
        if (RtsServerInfo.Type == TargetCoordinateType.MARCH_3)
        {
            Mono.SetTouchable(value && RtsServerInfo.visible);
        }
        else
        {
            Mono.SetTouchable(value);
        }
    }

    public void UpdateBasicInfoMonster(LuaTable heroList, Vector3 position)
    {
        if (MarchInfo.HeroList.Count == 0)
        {
            for (int i = 1; i <= heroList.Length; i++)
            {
                var heroId = heroList.Get<int, double>(i);
                MarchInfo.HeroList.Add((int) heroId);
            }

            MarchInfo.SetTeam(2);
        }

        ChangeSquareStateByMarchType();
    }

// TODO: 这个需要么？
    public void UpdateBasicInfoDefence(LuaTable heroList, Vector3 position)
    {
        if (MarchInfo.HeroList.Count == 0 && heroList!= null)
        {
            for (int i = 1; i <= heroList.Length; i++)
            {
                var heroId = heroList.Get<int, double>(i);
                MarchInfo.HeroList.Add((int) heroId);
            }

            MarchInfo.SetTeam(2);
        }

        ChangeSquareStateByMarchType();
    }

    public void UpdateEscapeInfo()
    {
        MarchInfo.ClientMarchStatue = EMarchStatus.Escape;
        _marchSquare?.CheckNeedResetChildrenNum(0);
        if (_deadStartTime == -1)
        {
            _deadStartTime = TimeUtils.GetClientTickTimeMS();
            _deadDuration = 1.5f;
            _deadRotateTime = 1f;
            _deadCheckSoldier = 0.05f;
            _deadAlphaTime = 0;
        }
    }

    public void StartCrossingGate(bool needShowTransition = true)
    {
        _marchSquare?.StartCrossingGate(needShowTransition);
    }

    public void EndCrossingGate()
    {
        _marchSquare?.EndCrossingGate();
    }

    public void SetMarchDataToSquareData()
    {
        ChangeSquareStateByMarchType();
        _marchSquare?.SetMarchDataToSquareData();
    }

    public void SetTargetId(long targetId)
    {
        if (targetId != MarchInfo.TargetId)
        {
            MarchInfo.SetTargetId(targetId);
        }
    }
    [BlackList]
    public void SetBattleTargetId(long battleTargetId,TargetCoordinateType attackTargetType)
    {
        if (MarchInfo.BattleTargetId!= battleTargetId || attackTargetType != MarchInfo.attackTargetType)
        {
            MarchInfo.SetBattleTargetId(battleTargetId,attackTargetType);
            Hud?.SetBattleTargetId(battleTargetId,attackTargetType);
        }
    }

    public void StopMarch(Vector3 position, bool forceRefresh = false)
    {
        ChangeSquareStateByMarchType();
    }

    public void UpdateRadius(float radius)
    {
        this.Radius = radius;
    }

    //private TroopsSoldier[] soldierList;

    [BlackList]
    // 该方法用来确定小兵数量，以及确定显示方阵的兵种；
    // 干的事情有点多，待优化
    public int SetAndGetSoldierCountByServerSoldierList(int soldierCount,int initSoldierCount,MarchType marchType)
    {
        if (marchType == MarchType.DIE_5)
        {
            soldierCount = 0;
        }
        if (ClientMarchType == EClientMarchType.Scout || ClientMarchType == EClientMarchType.Rescue) // 侦察队列
        {
            soldierCount = Int32.MaxValue; // 策划配置了301的数量，侦察又没有兵，这里给个最大值
        }
        else
        {
            MarchInfo.SoldierCount = soldierCount;
            MarchInfo.InitSoldierCount = initSoldierCount;
        }
        return soldierCount;
    }

    /// <summary>
    /// 根据士兵数量更新方阵
    /// </summary>
    /// <param name="soldierCount"></param>
    internal void UpdateSoldierInfo(int soldierCount)
    {
        _marchSquare?.UpdateSoldierInfo(soldierCount);
    }

    /// <summary>
    /// 根据士兵数量更新方阵
    /// </summary>
    /// <param name="soldierCount"></param>
    internal void UpdateSoldierInfo()
    {
        _marchSquare?.UpdateModelSoldierNum();
    }

    public void CheckNeedResetChildrenNum(int soldierCount)
    {
        _marchSquare?.CheckNeedResetChildrenNum(soldierCount);
    }
    
    public void CheckNeedResetMarchSkin(int marchResId)
    {
        _marchSquare?.CheckNeedResetMarchSkin(marchResId);
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="showBattleSquare"></param>
    /// <param name="changeStateByMarchType"></param>
    [BlackList]
    public void UpdateSquareVisible(bool showBattleSquare,bool changeStateByMarchType=true)  //这个将其他隐藏的都在这里处理吧。。。
    {
        //TODO: 这里的显示和不显示判断有些零散； 应该在一个地方统一处理
        if (showBattleSquare && MarchManager.marchContext.showMarchSquare)
        {
            if (!HasMarchSquare())
            {
                if (MarchInfo.MarchType != MarchType.DEFENCE_6)
                {
                    IsWaitDelete = false;
                    //Profiler.BeginSample("[C#]MarchManager.UpdateMarchInfo.Square.GetSquare");
                    _marchSquare = RTSClassPoolManager.GetMarchSquare();
                    //Profiler.EndSample();
                    //Profiler.BeginSample("[C#]MarchManager.UpdateMarchInfo.Square.Initialize");
                    _marchSquare.Initialize(this);
                    //Profiler.EndSample();
                    MarchInfo.SetLastPosition(MarchInfo.Position);

                    if (!IsSpriteSquare() && !IsNotShowModel())
                    {
                        _marchSquare.InitModel();
                    }
                    if (!IsModelOnly())
                    {
                        var soldierCount = RtsServerInfo.soldierCount;
                        UpdateSoldierInfo(soldierCount);
                        _marchSquare?.CheckNeedResetChildrenNum(RtsServerInfo.soldierCount, true);
                    }

                    //Profiler.EndSample();
                    if (changeStateByMarchType || needChangeSquareStateByMarchType)
                    {
                        needChangeSquareStateByMarchType = false;
                        //Profiler.BeginSample("[C#]MarchManager.UpdateMarchInfo.Square.ChangeState");
                        ChangeSquareStateByMarchType();
                        //Profiler.EndSample();
                    }
                }
            }
            else
            {
                _marchSquare?.CheckNeedResetChildrenNum(RtsServerInfo.soldierCount);
                _marchSquare?.CheckNeedResetMarchSkin(RtsServerInfo.marchSkinResId);
                if (RtsServerInfo.needReloadFormation)
                {
                    RtsServerInfo.needReloadFormation = false;
                    if (_marchSquare != null)
                    {
                        _marchSquare.Dispose();
                        RTSClassPoolManager.RecoverMarchSquare(_marchSquare);
                        _marchSquare = null;
                    }

                    _marchSquare = RTSClassPoolManager.GetMarchSquare();
                    _marchSquare.Initialize(this);
                    if (!IsModelOnly())
                    {
                        var soldierCount = RtsServerInfo.soldierCount;
                        UpdateSoldierInfo(soldierCount);
                        _marchSquare?.CheckNeedResetChildrenNum(RtsServerInfo.soldierCount, true);
                    }
                    if (changeStateByMarchType || needChangeSquareStateByMarchType)
                    {
                        needChangeSquareStateByMarchType = false;
                        ChangeSquareStateByMarchType();
                    }
                }
                //高LOD创建的MarchSquare，但是没有modelName，因此这里需要额外检查一步
                if (!IsSpriteSquare()&& !IsNotShowModel())
                {
                    _marchSquare.InitModel();
                }
            }

            ShowSquare();
            if (isClientCreateMarch())
            {
                SetTouchable(false);
            }
            else if (isMonster || RtsServerInfo.Type == TargetCoordinateType.SMUGGLER_30)
            {
                UpdateMonsterColliderEnabled(MarchManager.marchContext.LodLevel);
            }
            else
            {
                SetTouchable(true);
            }
        }
        if (!showBattleSquare && MarchManager.marchContext.showMarchSquare)
        {
            if (Hud != null  && Hud.MarchHudLod0 != null)
            {
                Hud.MarchHudLod0?.SetDefaultTitleActive();
            }
            HideSquare();
            SetTouchable(false);
        }
        isMarchVisibleInLod = MarchManager.marchContext.showMarchSquare;
    }

    public bool IsSpriteSquare()
    {
        return string.IsNullOrEmpty(RtsServerInfo.modelName);
    }

    // 不显示模型
    public bool IsNotShowModel()
    {
        return ClientCreateMarch == 3; // 客户端列车防守部队 只需要显示战斗hud
    }
    
    private bool IsModelOnly()
    {
        // return RtsServerInfo.Type == TargetCoordinateType.ALLIANCE_PRACTICE_BOSS_32
        //     || RtsServerInfo.Type == TargetCoordinateType.WORLD_BOSS_44;
        return !string.IsNullOrEmpty(RtsServerInfo.modelName);
    }

    public void DisposeHud()
    {
        if (Hud != null)
        {
            Hud.Dispose();
            if (Hud is MarchHud marchHud)
            {
                ArmyManager.Instance.HudManager.RecoverMarchHudCls(marchHud);
            }
            else if (Hud is WonderNpcHud wonderNpcHud)
            {
                ArmyManager.Instance.HudManager.RecoverWonderNpcHudCls(wonderNpcHud);
            }
            else if (Hud is SmugglerHud smugglerHud)
            {
                ArmyManager.Instance.HudManager.RecoverSmugglerNpcHudCls(smugglerHud);
            }
            else if (Hud is MonsterHud monsterHud)
            {
                ArmyManager.Instance.HudManager.RecoverMonsterHudCls(monsterHud);
            }
            Hud = null;
        }
    }

    private bool hudVisible = false;

    public bool IsHudShown()
    {
        return hudVisible && Hud != null;
    }

    public void HideHud()
    {
        if (Hud != null)
        {
            Hud.Hide();
        }
        hudVisible = false;
    }

    public void SetHeroIcon(RtsServerInfo serverInfo)
    {
        if (Hud is MarchHud marchHud)
        {
            marchHud.SetHeroIcon(serverInfo.heroIconList);
        }
    }

    public void ShowCargoTruckHud(RtsServerInfo serverInfo, MarchContext marchContext)
    {
        hudVisible = true;

        if (Hud == null)
        {
            Hud = ArmyManager.Instance.HudManager.GetCargoTruckHudClsFromPool();
        }
        CargoTruckHud cargoTruckHud = Hud as CargoTruckHud;
        cargoTruckHud.SetEntityAndTroopData(this, serverInfo);
        cargoTruckHud.Initialize(serverInfo.team);
        cargoTruckHud.OnInit(marchContext);
        cargoTruckHud.Show();
        cargoTruckHud.UpdateShow();
    }

    public void ShowMarchHud(RtsServerInfo serverInfo,MarchContext marchContext)
    {
        hudVisible = serverInfo.visible;

        if (Hud == null)
        {
            Hud = ArmyManager.Instance.HudManager.GetMarchHudClsFromPool();
        }
        MarchHud marchHud = Hud as MarchHud;
        marchHud.SetEntityAndTroopData(this, serverInfo);
        marchHud.Initialize(serverInfo.team);
        marchHud.OnInit(marchContext);
        if (hudVisible)
        {
            marchHud.Show();
        }
        else
        {
            marchHud.Hide();  
        }
    }

    public void ShowPractiseBossHud(RtsServerInfo serverInfo, MarchContext marchContext)
    {
        hudVisible = true;

        if (Hud == null)
        {
            Hud = ArmyManager.Instance.HudManager.GetPractiseHudClsFromPool();
        }
        PractiseMarchHud marchHud = Hud as PractiseMarchHud;
        marchHud.SetEntityAndTroopData(this, serverInfo);
        marchHud.Initialize(serverInfo.team);
        marchHud.OnInit(marchContext);
        marchHud.Show();
    }
    public void ShowWorldBossHud(RtsServerInfo serverInfo, MarchContext marchContext)
    {
        hudVisible = true;

        if (Hud == null)
        {
            Hud = ArmyManager.Instance.HudManager.GetWorldBossHudClsFromPool();
        }
        WorldBossHud worldBossHud = Hud as WorldBossHud;
        worldBossHud.SetEntityAndTroopData(this, serverInfo);
        worldBossHud.Initialize(serverInfo.team);
        worldBossHud.OnInit(marchContext);
        worldBossHud.Show();
    }
    public void ShowMonsterHud(RtsServerInfo serverInfo,MarchContext marchContext)
    {
        hudVisible = true;
        var isWonderNpc = serverInfo.IsWonderNpc();
        if (Hud == null)
        {
            if (isWonderNpc)
            {
                Hud = ArmyManager.Instance.HudManager.GetWonderNpcHudClsFromPool();
            }
            else if (serverInfo.IsSumggler())
            {
                Hud = ArmyManager.Instance.HudManager.GetSmugglerNpcHudClsFromPool();
            }
            else
            {
                Hud = ArmyManager.Instance.HudManager.GetMonsterHudClsFromPool();
            }

        }

        var monsterHud = Hud as MonsterHud;
        monsterHud.SetEntityAndTroopData(this, serverInfo);
        monsterHud.Initialize((int)MarchTeam.Other);
        //Profiler.EndSample();
        //Profiler.BeginSample("[C#]MarchManager.UpdateMarchInfo.HudOnInit");
        monsterHud.OnInit(marchContext);
        if (isWonderNpc)
        {
            monsterHud.SetTeam(serverInfo.team);
        }
        monsterHud.UpdatePlayerName();
        monsterHud.Show();
        //Profiler.EndSample();
    }

    public void ShowSmugglerHud(RtsServerInfo serverInfo,MarchContext marchContext)
    {
        hudVisible = true;
        if (Hud == null)
        {
            Hud = ArmyManager.Instance.HudManager.GetSmugglerNpcHudClsFromPool();
        }

        var monsterHud = Hud as MonsterHud;
        monsterHud.SetEntityAndTroopData(this, serverInfo);
        monsterHud.Initialize((int)MarchTeam.Other);
        monsterHud.OnInit(marchContext);
        monsterHud.UpdatePlayerName();
        monsterHud.Show();
    }

    public void ClearChasingTroopState(string targetId)
    {
        if (string.IsNullOrEmpty(targetId))
        {
            return;
        }
        ArmyManager.Instance.MarchManager.SetChasingTroopState(targetId,false);
    }

    public void PlayDeathAndRunAwayEffect()
    {
        if (isMonster)
        {
            _marchSquare?.SetEscapeWithoutAmbulance();
            MarchManager.Instance.CreateEsCapeEffect(Position);
            _marchSquare?.Death();
        }
        else if (TargetCoordinateType == TargetCoordinateType.ASSEMBLY_20)
        {
            _marchSquare?.SetEscapeWithoutAmbulance();
        }
        else
        {
            _marchSquare?.Death();
        }
        MarchInfo.SetServerMarchTypeAndStatus(MarchStatus.REMOVE_4, MarchType.DIE_5);
        Hud?.OnUpdateMarchTypeAndStatus();
        RoundFightPlayer.Inst.RemoveDirectionEffect(MarchInfo.Uid);
        DisposeHud();
        if (isMonster)
        {
            SetTouchable(false);
        }
    }

    public void PlayDeathOnlyHideEffect()
    {
        //_marchSquare?.Death();
        //_marchSquare?.SetArmyVisible(false);
        _marchSquare?.SetStartHide();
        Hud?.OnUpdateMarchTypeAndStatus();
        RoundFightPlayer.Inst.RemoveDirectionEffect(MarchInfo.Uid);
        DisposeHud();
        if (isMonster)
        {
            SetTouchable(false);
        }
    }
    public void PlayBossDead()
    {
        _marchSquare?.Death();
        MarchInfo.SetServerMarchTypeAndStatus(MarchStatus.REMOVE_4, MarchType.DIE_5);
        Hud?.OnUpdateMarchTypeAndStatus();
        RoundFightPlayer.Inst.RemoveDirectionEffect(MarchInfo.Uid);
        DisposeHud();
        PlayBossDeadEffect();
    }

    public void PlayBossVanish()
    {
        MarchInfo.SetServerMarchTypeAndStatus(MarchStatus.REMOVE_4, MarchType.DIE_5);
        Hud?.OnUpdateMarchTypeAndStatus();
        RoundFightPlayer.Inst.RemoveDirectionEffect(MarchInfo.Uid);
        DisposeHud();
    }

    private void PlayBossDeadEffect()
    {

    }

    public void PlayMonsterGotoBuilding()
    {
        SetTouchable(false);
        HideSquare();
        FakeMoveForward(Position,Position + Forward *  5);
        RoundFightPlayer.Inst.RemoveDirectionEffect(MarchInfo.Uid);
        DisposeHud();
    }
    
    public void ShowTsanTip(bool isWebHead, string headPath, string framePath, string desc)
    {
        Hud.SetTsanTip(isWebHead, headPath, framePath, desc);
    }
    
    public void RemoveTsanTip()
    {
        Hud.RemoveTsanTip();
    }

    //移除方阵
    [BlackList]
    public void HideSquare()
    {
        Visible = false;
        StopMoveSound();
        if (_marchSquare != null)
        {
            _marchSquare.BeforeHide();
        }
    }


    //显示方阵
    [BlackList]
    public void ShowSquare()
    {
        if (!Visible)
        {
            Visible = true;
            if (_marchSquare != null)
            {
                _marchSquare.ShowSquare();
                //_marchSquare.ResetFormation();
            }
        }
    }
    private int lastRage = 0;
    [BlackList]
    // 简略信息，战斗时推送，频繁
    public void RoundFight(int rage, int soldierCount,int totalSoldierCount,bool isInBattle,int costRage)
    {
        if (ArmyManager.IsDebug)
        {
            Debug.LogError(Tid + " 收到roundFight的延时" + (TimeUtils.GetClientTickTime() - MarchInfo.SetClientInBattleTime).ToString()+" 时间戳:"+TimeUtils.GetClientTickTimeMS());
        }
        MarchInfo.SoldierCount = soldierCount;
        ChangeSquareStateByMarchType();
        _marchSquare?.SetSoldierNum(soldierCount);
        MarchInfo.FightFrameTime = TimeUtils.GetClientTickTime();
        if (isInBattle && !MarchInfo.ServerInbattle)
        {
            lastRage = 0;
        }
        if (Hud != null)
        {
            Hud.UpdateRage(rage, lastRage, costRage);
            Hud?.RoundFight(soldierCount,totalSoldierCount, isInBattle);
        }
        MarchInfo.SetIsInBattle(isInBattle);
        _marchSquare?.SetIsInBattle(isInBattle);
        if (!isInBattle)
        {
            if (MarchInfo.ClientMarchStatue != EMarchStatus.Collect)
            {
                MarchInfo.SetIsClientInBattle(isInBattle);
            }
        }
        else
        {
            MarchInfo.SetIsClientInBattle(isInBattle);
        }
        lastRage = isInBattle ? rage : 0;
    }

    public void ResetLastRage()
    {
        lastRage = 0;
    }


    /// <summary>
    /// 服务器的roundfight通知战斗结束
    /// 需要处理特殊情况（脱战后又开战，先收到troopmarch，在收到之前的脱战roundfight，则需要认为这个roundfight脱战无效）
    /// </summary>
    public void SetRoundFightOver()
    {
        if (RtsServerInfo.marchType == MarchType.ATTACK_1 && TimeUtils.GetClientTickTime() - MarchInfo.FightFrameTime <= 3)
        {
            return;
        }
        IsInBattle = false;
    }



    public void SetMarchStatus(EMarchStatus marchstatus)
    {
        //Debug.LogError(Tid + "SetMarchStatus" + marchstatus);
        //        Debug.Log("uid"+MarchInfo.Uid+ "----------------------------------marchType:" + marchType);
        Profiler.BeginSample("SetMarchStatus");
        MarchInfo.SetMarchStatue(marchstatus);
        Profiler.EndSample();

        Profiler.BeginSample("ChangeSquareStateByMarchType");
        ChangeSquareStateByMarchType();
        Profiler.EndSample();

        if (marchstatus == EMarchStatus.Battle || marchstatus == EMarchStatus.ClientBattle)
        {
            //MarchManager.OnAttackCreated(MarchInfo.Uid, MarchInfo.BattleTargetId);
            //Profiler.BeginSample("GetBattleTarget");
            var target = GetBattleTarget();
            //Profiler.EndSample();
            if (target != null)
            {
                target.Hud?.SetIsInBattle(true);
                Hud?.SetIsInBattle(true);
            }
            else
            {
                /*if(MarchManager.marchContext.LodLevel >= WorldEntry.MaxShowMarchLodLevel && MarchInfo.Team == (int)MarchTeam.Self)
                {
                    Hud?.SetClientIsInBattle(true);
                }*/
                Hud?.SetIsInBattle(true);
                //Hud?.OnUpdateMarchTypeAndStatus();
            }
            MarchInfo.SetClientInBattleTime = TimeUtils.GetClientTickTime();
        }
        else
        {
            //不在战斗状态重置怒气英雄Id
            m_curRageHeroIdx = 0;
        }
        Hud?.OnUpdateMarchTypeAndStatus();
    }

    public bool isMarchVisibleInLod = true;
    [BlackList]
    public void Update(MarchContext context, float time)
    {
        UpdateBattleState();
        
        if (IsTruckAttacking())
        {
            UpdatePlayTruckAttacking();
        }

        if (isPlayingTrainDefending)
        {
            UpdatePlayTrainDefending();
        }

        if (isReadyToHide && Time.time - readyToHideTime > 2)
        {
#if DEVELOPMENT_BUILD || UNITY_EDITOR
            if (!isArenaMarch && !isMonster)
            {
                //Debug.LogError(Tid+"没有被删除，因此客户端自行删除");
            }
#endif
            var isVisible = false;
            if (isMonster)
            {
                var cameraManager = WorldCameraManager.GetInstance();
                if (cameraManager)
                {
                    isVisible = cameraManager.CheckPosInServerRect(Position);
                }
            }
            if (!isVisible)
            {
                MarchManager.Instance.DelayDestroyMarch(Tid,(int)RtsServerInfo.Type);
            }
            isReadyToHide = false;
        }
        //Profiler.BeginSample("[C#]_marchSquare.UpdateSquareVisible");
        if (!HasMarchSquare()) //未初始化
        {
            if(context.showMarchSquare && MarchInfo.NeedShowSquare()) //未初始化小兵显示
            {
                UpdateSquareVisible(true);
            }
            else
            {
                if (Hud != null)
                {
                    Hud.UpdateFollowPos();
                }
                //Profiler.EndSample();
                return;  //小兵不显示，不用往下走；可以勇哥其他状态
            }
        }
        //Profiler.EndSample();
        if (context.needUpdateLod)
        {
            //Profiler.BeginSample("[C#]MarchSquare.OnGlobalScaleChanged");
            _marchSquare?.OnGlobalScaleChanged(context.MarchLodLevel, context.Lod0Scale);
            //Profiler.EndSample();
            if (isMonster || RtsServerInfo.Type == TargetCoordinateType.SMUGGLER_30)
            {
                UpdateMonsterColliderEnabled(context.MarchLodLevel);
            }
        }

        if (context.MarchLodLevel < WorldEntry.MaxShowMarchLodLevel)
        {
            //Profiler.BeginSample("[C#]MarchEntity.UpdateMarch");
            UpdateMarch(time);
            //Profiler.EndSample();

            //Profiler.BeginSample("[C#]MarchSquare.Update");
            _marchSquare?.Update(time,context.MarchLodLevel);
            //Profiler.EndSample();
        }
        else
        {
            isMarchVisibleInLod = false;
        }

        //lua端部队删除失败，可能是服务器没推送到，也可能是lua报错，这边做个容错
        
        //
        // Profiler.BeginSample("[C#]MarchSquare.UpdateEscape");
        // //UpdateEscape(time);
        // Profiler.EndSample();
        CheckRtsServerInfoChanged();
        Profiler.BeginSample("[C#]Hud.UpdateFollowPos");
        if (Hud != null)
        {
            Hud.UpdateFollowPos();
        }
        Profiler.EndSample();
        
        if (delayRemoveTime >= 0)
        {
            if (Time.time > delayRemoveTime)
            {
                var attackTarget = GetBattleTarget();
                if (attackTarget != null)
                {
                    var marchInfo = attackTarget.MarchInfo;
                    marchInfo.SetIsInBattle(false);
                    marchInfo.SetIsClientInBattle(false);
                    marchInfo.SetIsJustLeaveBattle(true);
                    var hud = ((MarchHud)attackTarget.Hud);
                    if (hud != null)
                    {
                        hud.SetIsInBattle(false);
                        hud.SetIsTruckFighting(false);
                        hud.SetIsTrainFighting(false);
                    }
                }
                ReadyToHide();
                delayRemoveTime = -1;
            }
        }
    }

    /// <summary>
    /// 用于判断客户端脱战
    /// </summary>
    private void UpdateBattleState()
    {
        if (isTruckFighting || isTrainFighting)
        {
            return;
        }
        bool needLeaveBattle = false;
        var time = TimeUtils.GetClientTickTime();
        if ((MarchInfo.FightFrameTime == 0 && MarchInfo.ServerInbattle || MarchInfo.FightFrameTime > 0 && time - MarchInfo.FightFrameTime > 3f)
            && MarchInfo.ClientMarchStatue != EMarchStatus.Collect) //脱离战斗后几秒UI变成正常状态
        {
#if UNITY_EDITOR
            Debug.Log($"部队{MarchInfo.Uid}因roundfight超时而脱战" + " 当前时间:"+ time + " roundfight时间" + MarchInfo.FightFrameTime);

#endif
            needLeaveBattle = true;
        }
        else if (time - MarchInfo.SetClientInBattleTime > 3 && MarchInfo.IsClientInBattle && MarchInfo.ClientMarchStatue != EMarchStatus.Collect)
        {
            if (!MarchInfo.ServerInbattle)
            {
#if UNITY_EDITOR
                Debug.Log($"部队{MarchInfo.Uid}因未接受到roundfight协议脱战" + " 时间戳:"+TimeUtils.GetClientTickTimeMS());

#endif
                needLeaveBattle = true;
            }
        }

        if (needLeaveBattle)
        {
            MarchInfo.FightFrameTime = 0;
            Hud?.SetIsInBattle(false);
            MarchInfo.SetIsInBattle(false);
            MarchInfo.SetIsClientInBattle(false);
            _marchSquare?.SetIsInBattle(false);
            ResetLastRage();
        }

    }

    [BlackList]
    public void UpdateOnWaitDispose()
    {
        if (_marchSquare == null)
        {
            IsWaitDelete = true;
        }
        else
        {
            _marchSquare?.UpdateOnWaitDispose();
        }
    }

    private bool needChangeSquareStateByMarchType = false;

    [BlackList]
    public void ChangeSquareStateByMarchType()
    {
        if (!HasMarchSquare())
        {
            //Debug.LogError(Tid+"没有方阵");
            needChangeSquareStateByMarchType = true;
            return;
        }
        //Debug.LogError(Tid + " ClientStatus " + MarchInfo.ClientMarchStatue);
        //Debug.Log(Time.frameCount + " MarchInfo ID" + MarchInfo.Uid + " ChangeSquareStateByMarchType    MarchInfo.Type:" + MarchInfo.ClientMarchStatue);
        if (IsMoving()) // || MarchInfo.IsPositionChanged()))// && MarchInfo.MarchType != MarchType.ATTACK_1)
        {
            _marchSquare?.Move();

            PlayMoveSound();

            if (_action == SquareAction.Attack )
            {
                if (EnemyTarget !=null)
                {
                    if (MarchInfo.TargetId == null && EnemyTarget.MarchInfo == null || MarchInfo.TargetId != EnemyTarget.MarchInfo.Uid)
                    {
                        _marchSquare?.ClearAttackState();
                    }
                }
            }

            if (MarchInfo.ClientMarchStatue == EMarchStatus.Escape)
            {
                //_marchSquare?.ShowAmbulance();
            }
            if (RtsServerInfo.Type == TargetCoordinateType.TRAIN_51) // 列车检查展开状态
            {
                _marchSquare?.UpdateTrainOutWonder();
            }
            _action = SquareAction.March;
        }
        else if (MarchInfo.ClientMarchStatue == EMarchStatus.Park)
        {
            StopMoveSound();
            if (MarchHelper.IsPveAssembleDismissed(RtsServerInfo))
            {
                
            }
            else if (RtsServerInfo.Type == TargetCoordinateType.SMUGGLER_30 && RtsServerInfo.marchStatus == MarchStatus.INIT_0)
            {
                _marchSquare?.PlayDeathFrame();
            }
            else
            {
                _marchSquare?.MoveToStand();
            }
            if (_action == SquareAction.Attack)
            {
                _marchSquare?.ClearAttackState();
//                MarchInfo.SetIsClientInBattle(false);
            }

            _action = SquareAction.Stay;
        }
        else if (MarchInfo.ClientMarchStatue == EMarchStatus.Battle)
        {
            StopMoveSound();

            _action = SquareAction.Attack;
            _marchSquare?.ReadyToAttack();
            MarchInfo.SetIsClientInBattle(true);
        }

        else if (MarchInfo.ClientMarchStatue == EMarchStatus.Collect)
        {
            StopMoveSound();
            _action = SquareAction.Attack;
            _marchSquare?.ReadyToCollect();
            MarchInfo.SetIsClientInBattle(true);
        }

        else if (MarchInfo.ClientMarchStatue == EMarchStatus.Escape)
        {
            StopMoveSound();
            _marchSquare.IsPincer = false;
            _marchSquare?.CheckNeedResetChildrenNum(0);
        }
        else
        {
            StopMoveSound();
            if (_action == SquareAction.Attack)
            {
                _marchSquare.IsPincer = false;
                _marchSquare?.ClearAttackState();
//                MarchInfo.SetIsClientInBattle(false);
            }
        }

        _marchSquare?.SetBesiege(isBesiege);
        _marchSquare?.OnMarchStatusChanged();
    }
    #region 音效控制部分
    /// <summary>
    /// 获取不同兵种对应的移动音效
    /// </summary>
    /// <param name="soldierType"></param>
    /// <returns></returns>
    private string GetMoveAudioName(int soldierType,int team)
    {
        switch (soldierType)
        {
            case (int)SoldierType.Motor:
                if(team == (int)MarchTeam.Self)
                {
                    return "am_sandbox_motomove_player";
                }
                else
                {
                    return "am_sandbox_motomove";
                }
            default:
                if (team == (int)MarchTeam.Self)
                {
                    return "am_sandbox_teammove_player";
                }
                else
                {
                    return "am_sandbox_teammove";
                }
        }
    }

    private string GetStopMoveName()
    {
        switch (currentMoveSound)
        {
            case "am_sandbox_motomove_player":
                return "am_sandbox_motomove_player_Stop";
            case "am_sandbox_motomove":
                return "am_sandbox_motomove_Stop";
            case "am_sandbox_teammove_player":
                return "am_sandbox_teammove_player_Stop";
            case "am_sandbox_teammove":
                return "am_sandbox_teammove_Stop";
            default:
                return "";
        }
    }

    private void PlayMoveSound()
    {
        int team = -1;
        if (ClientMarchType == EClientMarchType.March)
        {
            team = RtsServerInfo.team;
        }
        else
        {
            if (RtsServerInfo.team != 0)
            {
                team = RtsServerInfo.team;
            }
        }
        //行军部队声音
        if (ClientMarchType != EClientMarchType.Monster)
        {
            string moveSound = GetMoveAudioName(MarchInfo.SoldierType, team);
            if(moveSound != "" && ArmyManager.Instance.CanPlayAudio(team))
            {
                //如果是自己的,必然播放,否则限制播放数量
                //如果当前正在播放,直接禁止再次播放
                if((currentMoveSound == "") && ((RtsServerInfo.playerId != 0 && RtsServerInfo.team == (int)MarchTeam.Self) || (MarchManager.moveAudioCount < MarchManager.moveAudioCountLimit)))
                {
                    ///在这里判断是部队移动还是摩托移动
                    currentMoveSound = moveSound;
                    MarchManager.moveAudioCount++;
                    AudioManager.PlaySound(moveSound, GetAudioEmiterObject());
                }
            }
        }
    }

    private void StopMoveSound()
    {
        if (currentMoveSound != "")
        {
            AudioManager.PlaySound(GetStopMoveName(), GetAudioEmiterObject());
            currentMoveSound = "";
            MarchManager.moveAudioCount--;
        }
    }

    #endregion
    public void SetForward(Vector3 forward)
    {
        MarchInfo.SetForward(forward);
    }

    public bool IsMoving()
    {
        return MarchInfo.IsMarchSquareMoving();
    }


    [BlackList]
    public MarchSquare GetBattleSquare()
    {
        return _marchSquare;
    }

    [BlackList]
    public MarchEntity GetBattleTarget()
    {
        if (MarchManager == null)
        {
            return null;
        }
        return MarchManager.GetMarchEntityByIdAndType(MarchInfo.BattleTargetId,MarchInfo.attackTargetType);
    }

    public MarchEntity GetTarget()
    {
        return MarchManager.GetMarchEntityByIdAndType(MarchInfo.TargetId,MarchInfo.TargetType);
    }
    [BlackList]
    public long GetTargetId()
    {
        return MarchInfo.TargetId;
    }

    public void RemoveAttack()
    {
        MarchManager?.OnAttackRemoved(MarchInfo.Uid,TargetCoordinateType);
    }

    public Vector3 GetRandomSoldierPosition()
    {
        return MarchInfo.Position;
    }

    private HashSet<string> ignoreNameMarchInfo = new HashSet<string>{"MarchEntity","SoldierPositionIndexArray","SoldierPositionIndexArrayMirror"};
    private HashSet<string> ignoreNameHud = new HashSet<string>{"MarchEntity","MarchInfo"};
    private HashSet<string> ignoreNameMarchEntity = new HashSet<string>{"MarchInfo","RtsServerInfo","SoldierPositionIndexArrayMirror"};

    //如果是点击选中，则放大，不然不放大（比如拖动时）
    public void SetSelected(bool value,bool isClickSelected = false, bool isMultySelect = false)
    {
        if(IsSelected != value)
        {
            IsSelected = value;
            Hud?.SetSelectedScale(value ? BattleUtils.SelectedHudScale : BattleUtils.UnSelectedHudScale);
            Hud?.SetSelected(value, isMultySelect);
            _marchSquare?.OnsetDefaultApertureActive(!value);
            if (value)
            {
                Mono.SetLayerTop();
            }
            if (value && ArmyManager.IsDebugMarch)
            {
                string log = string.Format("部队{0}最近一次服务器数据：", Tid);
                log = log + "\n";
                log = log + BattleUtils.ServerDataToString(RtsServerInfo);
                Debug.LogError(log);
                log = string.Format("部队{0}客户端MarchInfo：", Tid);
                log = log + "\n";
                log += BattleUtils.ObjectToString(MarchInfo,"MarchInfo",0,2,ignoreNameMarchInfo);
                Debug.LogError(log);
                log = string.Format("部队{0}客户端MarchSquare：", Tid);
                log = log + "\n";
                log += _marchSquare?.GetDebugContent();
                Debug.LogError(log);
                if (Hud != null)
                {
                    log = string.Format("部队{0}客户端MarchHud：", Tid);
                    log = log + "\n";
                    log += BattleUtils.ObjectToString(Hud,"Hud",0,2,ignoreNameHud);
                    Debug.LogError(log);
                }
            }
        }

#if UNITY_EDITOR
        if (value)
        {
            UnityEditor.EditorGUIUtility.PingObject(this.GetGameObject());
            UnityEditor.Selection.activeGameObject = GetGameObject();
        }
#endif
    }

    private bool isBeforeDispose = false;

    [BlackList]
    public void OnBeforeDispose()
    {
        isReadyToHide = false;
        isBeforeDispose = true;
        forwardObjList.Clear();
        _marchSquare?.BeforeDispose();
        _deadStartTime = -1;
        _deadHudShowTime = -1;
        //DisposeHud();
        HideHud();
        //Object.Destroy(Mono.gameObject);
        Mono.Dispose();
        MarchBesiegeManager.Instance.RemoveAttacker(Tid,TargetCoordinateType);
        simulatedBesiegeAngle = -1;
        isClientInBattle = false;
        flyTextTimeOffset = 0;
        StopMoveSound();
        if (isMonsterBattleSoundDirty)
        {
            AudioManager.StopSound("sfx_rts_battle_team", GetAudioEmiterObject());
            isMonsterBattleSoundDirty = false;
        }

        RoundFightPlayer.Inst.RemoveDirectionEffect(Tid);
        //Mono = null;
        m_curRageHeroIdx = 0;
        isPlayingTruckAttacking = false;
        isPlayingTrainDefending = false;
    }


    [BlackList]
    public void Dispose()
    {
        isReadyToHide = false;
        if (_marchSquare != null)
        {
            _marchSquare.Dispose();
            RTSClassPoolManager.RecoverMarchSquare(_marchSquare);
        }
        DisposeHud();
        DisposeSkill();
        isBeforeDispose = false;

        _marchSquare = null;
        MarchInfo.Dispose();
        EnemyTarget = null;
        lastPosition = default;
        defaultForward = default;
        simulatedBesiegeAngle = -1;
        isMonster = false;
        isMonsterBattleSoundDirty = false;
        if (isFakeParent)
        {
            if (childEntities != null)
            {
                for (int i = 0; i < childEntities.Count; i++)
                {
                    var type = (int) childEntities[i].TargetCoordinateType;
                    var id = childEntities[i].Tid;
                    MarchManager.RemoveFakeChildren(type,id);
                    MarchManager.DestroyMarch(id,type);
                }
                childEntities.Clear();
            }
            MarchManager.RemoveFakeParent((int)TargetCoordinateType,Tid);
        }
        MarchManager = null;
        isFakeParent = false;
        isFakeChild = false;
        childEntities = null;
        IsSelected = false;
        if (RtsServerInfo!=null)
        {
            RTSClassPoolManager.RecoverRtsServerInfo(RtsServerInfo);
            RtsServerInfo = null;
        }

        isArenaMarch = false;
        isArenaMarchInDeck = false;
        IsInBattle = false;
        isExpeditionMarch = false;
        isExpeditionMarchInDeck = false;
        isExpeditionMarchMoving = false;
        bIsCargoTruckFakeMarch = false;
        isTruckFighting = false;
        delayRemoveTime = -1;
        isPlayingTruckAttacking = false;
        truckAttackerBehaviour = null;
        isPveBattleWin = false;
        isPortraitRotated = false;
        isTrainFighting = false;
        ClientCreateMarch = 0;
        isPlayingTrainDefending = false;
        trainDefenceBehaviour = null;
    }

    [BlackList]
    public void ResetMarchSquare()
    {
        if (_marchSquare != null)
        {
            _marchSquare.Dispose();
            RTSClassPoolManager.RecoverMarchSquare(_marchSquare);
            _marchSquare = null;
        }

        UpdateSquareVisible(MarchInfo.NeedShowSquare());
    }
    private void UpdateEscape(float time)
    {
        if (MarchInfo.ClientMarchStatue == EMarchStatus.Escape)
        {
            var poor = time - _deadStartTime;
            if (_deadCheckSoldier > 0 && poor >= _deadCheckSoldier)
            {
                _marchSquare?.CheckSoldierDeadOrReborn(MarchInfo.SoldierCount);
                _deadCheckSoldier = -1f;
            }
            else if (_deadRotateTime > 0 && poor >= _deadRotateTime)
            {
                _marchSquare?.SetChildrenForward(-_marchSquare.Forward);
                _deadRotateTime = -1f;
            }
            else if (poor >= _deadDuration)
            {
                SetMarchStatus(EMarchStatus.WALK);
                _deadStartTime = -1;
                _deadHudShowTime = time;
                if (ClientMarchType == EClientMarchType.Monster)
                {
                    _deadAlphaTime = time;
                }

                ChangeSquareStateByMarchType();
            }
        }
        else
        {
            if (_deadHudShowTime > 0)
            {
                var poor = time - _deadHudShowTime;
                if (poor >= 1f)
                {
                    _deadHudShowTime = -1;
                }
            }

            if (_deadAlphaTime > 0)
            {
                _marchSquare?.SetChildrenAlpha(1.5f - (time - _deadHudShowTime));
            }
        }
    }

    public int squareDataIndex => _marchSquare.squareDataIndex;

    const float maxCorrectDistance = 3;
    // 这个是每帧都在调用
    private void UpdateMarch(float time)
    {
        if (!HasMarchSquare())
        {
            return;
        }

        bool forceMoveChild = false;
        if (MarchInfo.IsMarchSquareMoving())
        {
            //forceMoveChild = Vector3.Distance(MarchInfo.Position, MarchInfo.LastPosition) >= maxCorrectDistance;
            if (MarchInfo.ClientAttackPosition != Vector3.zero &&
                Vector3.Distance(MarchInfo.ClientAttackPosition, MarchInfo.Position) < 0.05f)
            {
                _marchSquare?.ClientSetMarchAndTargetInBattle();
            }
            //else
            //{
            //    _marchSquare?.SetChildrenPosition(forceMoveChild);
            //}
            //
            // _marchSquare?.SetForward(MarchInfo.CurrentForward, forceMoveChild);
            // _marchSquare?.MoveSmokePosition();
            /*if (MarchInfo.Uid == MarchSequareConstant.DebugUid.ToString())
            {
                Debug.Log(LogModule.RTS,$" framecount:{Time.frameCount} {MarchInfo.Uid}-0X UpdatePosition {MarchInfo.Position} ");
            }*/
            //TODO: 这个可以用MarchInfo.IsPositionChanged()么？
            if (MarchInfo.IsPositionChanged())
            {
                _marchSquare?.SetPosition(MarchInfo.Position,MarchInfo.IsForceMoveChild);
                lastPosition = MarchInfo.Position;
                MarchInfo.SetLastPosition(MarchInfo.Position);
            }

            //这个最好在状态改变的时候算，而不是每帧做
            //CheckNeedRefreshSegmentStartTime();
            // SquareDataManager.Instance.SetForward(squareDataIndex,MarchInfo.CurrentForward);
        }
        else if (MarchInfo.ClientMarchStatue == EMarchStatus.Battle)
        {
            //战斗状态 每1s更新一下朝向： 目标可能会移动，这时候需要调整方向、
            if (time - this.lastUpdateFightForwardTime > MarchSequareConstant.BattleCheckForwardDural)
            {
                var forward = MarchInfo.GetTargetPosition() - MarchInfo.Position;

                if (!AreVectorsEqual(MarchInfo.CurrentForward.normalized,forward.normalized))
                {
                    SetForward(forward.normalized);
                    _marchSquare?.SetServerPosChanged();
                }
                this.lastUpdateFightForwardTime = time;
            }

            //UpdateBattleEffect(deltaTime);
        }
        _marchSquare?.SetForward(MarchInfo.CurrentForward);

        var isClientInBattle = false;
        var battleTarget = GetBattleTarget();
        var targetPos = RtsServerInfo.targetPosition;
        if (MarchInfo.IsInBattleState && battleTarget != null)
        {
            _marchSquare?.SetClientInBattle(true, battleTarget.ClientMarchType == EClientMarchType.Defence,Team == 0 || battleTarget.Team == 0);
            isClientInBattle = true;
        }
        else if (MarchInfo.IsInBattleState && MarchInfo.ClientMarchStatue == EMarchStatus.Collect)
        {
            _marchSquare?.SetClientInBattle(true, false);
            SetForward((targetPos - MarchInfo.Position).normalized);
            isClientInBattle = true;
        }
        else
        {
            _marchSquare?.SetClientInBattle(false,false);
            if (isClientInBattle && !IsMoving())
            {
                SetForward(defaultForward);
            }
            isClientInBattle = false;
        }
        if (isClientInBattle != this.isClientInBattle)
        {
            this.isClientInBattle = isClientInBattle;
            if (!isClientInBattle)
            {
                MarchManager.Instance.CheckStopSelfBattle(Team,Team);
                SetForward(defaultForward);
            }
            //ChangeSquareStateByMarchType();
        }
    }

    private bool AreVectorsEqual(Vector3 vector1, Vector3 vector2, int decimalPlaces = 2)
    {
        double tolerance = Math.Pow(10, -decimalPlaces);

        return Math.Abs(vector1.x - vector2.x) < tolerance &&
               Math.Abs(vector1.y - vector2.y) < tolerance &&
               Math.Abs(vector1.z - vector2.z) < tolerance;
    }

    private bool isClientInBattle;

    /// <summary>
    ///  只是在战斗中使用，用来判断当前应该保留几个小兵；
    /// </summary>
    /// <param name="squareSoldierCount"></param>
    /// <returns></returns>
    public int UpateModelTotalNumBySoldierCount(int squareSoldierCount)
    {
        int mtn = 0 ;
        if (formationCfgs != null)
        {
            for (int i = formationCfgs.Count-1; i > -1; i--)
            {
                var cfg = formationCfgs[i];

                if (squareSoldierCount >= cfg.soldierNum)
                {
                    mtn = cfg.modelNum;
                    break;
                }
            }
        }
        else
        {
            Debug.LogWarning($"tid = {Tid}  阵型配置出错");
        }


        return mtn;
    }

    private bool HasMarchSquare()
    {
        return _marchSquare != null;
    }


    private Vector3 lastPosition;


    [BlackList]
    public void ClientStartFight()
    {
        _marchSquare?.ClientStartFight();
    }

    public void FakeKnockBack(Vector3 forward,int count,int externalSoldierId = -1)
    {
        _marchSquare?.FakeKnockBack(forward, count,externalSoldierId);
    }

    public void FakeMoveForward(Vector3 startPosition, Vector3 targetPosition,float speed = -1)
    {
        _marchSquare?.FakeMoveForward(startPosition, targetPosition,speed);
    }

    public void EndFakeMoveForward()
    {
        _marchSquare?.EndFakeForward();
    }

    private float readyToHideTime;
    private bool isReadyToHide;

    public void ReadyToHide()
    {
        if (!isReadyToHide)
        {
            readyToHideTime = Time.time;
            isReadyToHide = true;
        }
    }

    public void StopReadyToHide()
    {
        isReadyToHide = false;
    }

    public void UpdateHudHpPercent()
    {
        Hud?.UpdateHpToRealValue();
        if ((isArenaMarch || isExpeditionMarch)&& (!isArenaMarchInDeck && !isExpeditionMarchInDeck))
        {
            if (RtsArenaManager.Instance.ArenaType == 0)
            {
                ResidentHandler.Inst.GetFunction("L_RtsArenaManager.UpdateTroopData").Action(Tid, -1, MarchInfo.SoldierCount);
            }
            else if (RtsArenaManager.Instance.ArenaType == 1)
            {
                ResidentHandler.Inst.GetFunction("L_RadarArenaManager.UpdateTroopData").Action(Tid, -1, MarchInfo.SoldierCount);
            }
            else
            {
                ResidentHandler.Inst.GetFunction("L_RtsExpeditionManager.UpdateTroopData").Action(Tid, -1, MarchInfo.SoldierCount);
            }
        }
    }

    public void ShakeHud()
    {
        Hud?.Shake();
    }

    public void ResetFormation()
    {
        _marchSquare?.ResetFormation();
    }

    public Vector3 defaultForward;

    public void SetMarchDefaultForward(Vector3 forward)
    {
        defaultForward = forward;
    }
    public Vector3 GetMarchDefaultForward(long tid)
    {
        if (defaultForward == default)
        {

            var dir = tid % 8;
            defaultForward = Quaternion.AngleAxis(45 * dir, Vector3.up) * Vector3.forward;

        }
        return defaultForward;
    }

    [BlackList]
    public double GetSimulatedBesiegeAngle()
    {
        return simulatedBesiegeAngle;
    }

    private double simulatedBesiegeAngle = -1;

    [BlackList]
    public void CheckNeedCalculateBesiegeAngle(RtsServerInfo serverData)
    {
        // Debug.LogError(Tid + " " + serverData.besiegeFinalAngle + " " + serverData.marchStatus);
        if (serverData.targetId == 0 || serverData.attackTargetId == 0)
        {
            simulatedBesiegeAngle = -1;
            return;
        }

        if (serverData.besiegeFinalAngle == -1)
        {
            // Debug.LogError(Tid + " 真实夹角 " + serverData.besiegeFinalAngle);
            simulatedBesiegeAngle = -1;
            return;
        }

        //移动到战斗 就判断为需要夹击
        var isReadyToBattle = (serverData.marchStatus == MarchStatus.FIGHT_2 || serverData.marchStatus == MarchStatus.SIEGE_FIGHT_6 || serverData.marchStatus == MarchStatus.COLLECT_5);
        var IsWalkToPark = MarchInfo.IsWalkToPark || (serverData.pathList != null && serverData.pathList.Length > 0);
        if (IsWalkToPark && isReadyToBattle)
        {
            MarchInfo.IsWalkToPark = false;
            if (serverData.besiegeFinalAngle == -2)
            {
                simulatedBesiegeAngle = MarchBesiegeManager.Instance.GetBesiegeFinalAngle(Tid,TargetCoordinateType);

                if (simulatedBesiegeAngle >= 0)
                {
                    var besiegeCenter = serverData.besiegeCenter;
                    var finalPoint = besiegeCenter + Quaternion.AngleAxis(-(float)simulatedBesiegeAngle, Vector3.up) * Vector3.right *
                                     serverData.besiegeRadius;
                    var distance = Vector3.Distance(finalPoint, Position);
                    if (distance < 0.1f)
                    {
                        simulatedBesiegeAngle = -1;
                    }
                    // Debug.LogError(Tid + " 模拟夹角时的距离" + distance);
                }
            }
            else
            {
                // Debug.LogError(Tid + " lod4.besiegeFinalAngle != -2 ");
                simulatedBesiegeAngle = -1;
            }
        }
        else
        {
            // Debug.LogError(Tid + " not is readyToBattle");
            if ((serverData.marchStatus == MarchStatus.FIGHT_2 || serverData.marchStatus == MarchStatus.COLLECT_5) && serverData.besiegeFinalAngle == -2)
            {

            }
            else
            {
                simulatedBesiegeAngle = -1;
            }
        }

        if (simulatedBesiegeAngle >= 0)
        {
            serverData.besiegeFinalAngle = simulatedBesiegeAngle;
            serverData.pathList = null;
        }
    }

    [BlackList]
    public void CheckNeedGenerateBesiegePathList(RtsServerInfo serverData)
    {
        isBesiege = false;
        if (serverData.pathList == null || serverData.pathList.Length == 0)
        {
            if (serverData.besiegeRadius > 0 && serverData.besiegeFinalAngle >= 0)//说明正在夹击
            {
                float besiegeSpeedRatio = 1;
                serverData.pathList = GenerateBesiegePathList(serverData.coordinate, serverData.besiegeFinalAngle,serverData.besiegeCenter,serverData.besiegeRadius,serverData.speed / 3600,ref besiegeSpeedRatio,serverData.lastFrameTime);
                if (serverData.pathList != null)
                {
                    serverData.coordinate = new Coordinate
                    {
                        xAxis = Position.x,
                        zAxis = Position.z,
                    };
                    serverData.lastFrameTime = TimeUtils.GetServerTimeMs();
                    isBesiege = true;
                    // var besiegeString = Tid + " 生成夹击路径 ,角度:"+serverData.besiegeFinalAngle;
                    // besiegeString += "\n";
                    // besiegeString += "目标位置:" + serverData.besiegeCenter.x + "," + serverData.besiegeCenter.z;
                    // besiegeString += "\n";
                    // for (int i = 0; i < serverData.pathList.Length; i++)
                    // {
                    //     besiegeString += serverData.pathList[i].xAxis + "," + serverData.pathList[i].zAxis;
                    //     besiegeString += "\n";
                    // }
                    // Debug.LogError(besiegeString);
                }
                serverData.speed = serverData.speed * besiegeSpeedRatio;
            }
            else
            {
                // UnityEngine.Debug.LogError(Tid + "   lod4.besiegeRadius    " + serverData.besiegeRadius);
            }
        }
        else
        {
            // UnityEngine.Debug.LogError(Tid + " 路径部位空 ");
        }
    }

    private Coordinate[] GenerateBesiegePathList(Coordinate startPosition, double final,Vector3 besiegeCenter,float besiegeRadius,float speed,ref float besiegeSpeedRatio,long lastFrameTime)
    {

        float finalAngle = (float)final;
        float currentAngle;
        if ((RtsServerInfo.targetType == TargetCoordinateType.RESOURCE_5 || RtsServerInfo.targetType == TargetCoordinateType.ALLIANCE_RESOURCE_12) && RtsServerInfo.marchStatus == MarchStatus.COLLECT_5)
        {
            var forward = (Position - RtsServerInfo.targetPosition).normalized;
            currentAngle = PveUtils.GetAngleServer(Vector3.right, forward);
        }
        else
        {
            currentAngle = PveUtils.GetAngleServer(Vector3.right, AttackForward);
        }
        // Debug.LogError("MarchInfo.ClientMarchStatue " + MarchInfo.ClientMarchStatue + " " + Tid + " " + TargetCoordinateType);
        //先根据速度，算出服务器这一帧经过的路程,也就是弧长
        var serverTickTime = 1f;
        var l = speed * serverTickTime;
        //根据弧长，除以半径，得到角度
        var angleInterval = l * 180 / besiegeRadius / Mathf.PI;

        //客户端走直线，服务器走弧线，所以客户端要走的比服务器慢一点才能匹配
        var clientMoveDistance = Mathf.Sin(angleInterval * Mathf.Deg2Rad / 2) * besiegeRadius * 2;
        var serverMoveDistance = l;
        besiegeSpeedRatio = clientMoveDistance / serverMoveDistance;


        //当前角度，0~360，目标角度，0~360
        //判断应该往哪个方向转
        //先让最终值永远比当前值大
        if (finalAngle < currentAngle)
        {
            finalAngle += 360;
        }

        if (finalAngle - currentAngle < 0.1f)
        {
            return null;
        }


        //然后判断夹角差距是否大于180，如果大于则反向
        if (finalAngle - currentAngle > 180)
        {
            finalAngle -= 360;
            angleInterval = -angleInterval;
        }


        var isClientBesiege = MarchBesiegeManager.Instance.IsBesiegeFromClient(Tid,TargetCoordinateType);
        if (isClientBesiege)
        {
            var serverAngleDiff = Mathf.Abs(finalAngle - currentAngle);
            var serverArcLength = serverAngleDiff * Mathf.PI * besiegeRadius / 180;
            var serverMoveTime = serverArcLength / speed;
            var clientMoveTime = serverMoveTime + 1;
            besiegeSpeedRatio = besiegeSpeedRatio * serverMoveTime / clientMoveTime;
            besiegeSpeedRatio = Mathf.Max(besiegeSpeedRatio, 0.7f);
        }
        else
        {
            var serverForward = startPosition.ToVector3() - besiegeCenter;
            var serverCurrentAngle = PveUtils.GetAngleServer(Vector3.right, serverForward);
            var clientAngleDiff = Mathf.Abs(finalAngle - currentAngle);
            var clientArcLength = clientAngleDiff * Mathf.PI * besiegeRadius / 180;
            var serverAngleDiff = Mathf.Abs(finalAngle - serverCurrentAngle);
            var serverArcLength = serverAngleDiff * Mathf.PI * besiegeRadius / 180;
            var totalMoveTime = clientArcLength / speed;
            var passTime = (TimeUtils.GetServerTimeMs() - lastFrameTime) / 1000f;
            var serverMoveTime = serverArcLength / speed - passTime;
            //Debug.LogError(serverAngleDiff / 180 / speed);

            var ratio = totalMoveTime / serverMoveTime;

            ratio = Mathf.Max(ratio, 1);
            besiegeSpeedRatio = besiegeSpeedRatio * ratio;
            besiegeSpeedRatio = Mathf.Min(besiegeSpeedRatio, 1.5f);
        }

        int pointCount = (int)Mathf.Abs((finalAngle - currentAngle) / angleInterval);
        // Debug.LogError("pointCount:"+ pointCount + "  " + Tid + " " + TargetCoordinateType);
        var startForward = (Position - besiegeCenter).normalized;
        var finalPoint =  besiegeCenter + Quaternion.AngleAxis(-(float)final, Vector3.up) * Vector3.right * besiegeRadius;
        if (Vector3.Distance(finalPoint, Position) < 0.01f)
        {
            // Debug.LogError("到了");
            return null;
        }
        if (pointCount <= 0)
        {
            return new Coordinate[]
            {
                new Coordinate
                {
                    xAxis = Position.x,
                    zAxis = Position.z,
                },
                new Coordinate
                {
                    xAxis = finalPoint.x,
                    zAxis = finalPoint.z,
                },
            };
        }

        var pathList = new Coordinate[pointCount + 1];

        for (int i = 0; i < pointCount; i++)
        {
            var newPoint = besiegeCenter + Quaternion.AngleAxis(-i * angleInterval, Vector3.up) * startForward * besiegeRadius;
            pathList[i] = new Coordinate
            {
                xAxis = newPoint.x,
                zAxis = newPoint.z,
            };
        }

        pathList[pointCount] = new Coordinate
        {
            xAxis = finalPoint.x,
            zAxis = finalPoint.z,
        };
        // var str = Tid + " pathList";
        // for (int i = 0; i < pathList.Length; i++)
        // {
        //     str += "\n";
        //     str += pathList[i].xAxis + " " + pathList[i].zAxis;
        // }
        // Debug.LogError(str);
        // Debug.LogError(Tid + " distance" + BattleUtils.Distance(pathList[pointCount],startPosition));
        // Debug.LogError(Tid + " start" + Position.x + " " + Position.z);
        // Debug.LogError(Tid + " final" + finalPoint.x + " " + finalPoint.z);
        //  Debug.LogError("====================================================");
        return pathList;
    }

    public void CheckNeedGenerateChasePathList(MarchEntity target,RtsServerInfo serverData)
    {
        var chaseList = GenerateChasePathList(target);
        if (chaseList != null)
        {
            serverData.lastFrameTime = TimeUtils.GetServerTimeMs();
            //lod4.coordinate = chaseList[0];
            serverData.pathList = chaseList;
            if (serverData.speed > target.RtsServerInfo.speed && target.RtsServerInfo.speed!=0)
            {
                serverData.speed = target.RtsServerInfo.speed;
            }

            if (ArmyManager.IsChasingDebug)
            {
                var str = target.Tid + "客户端模拟追击，路点:";
                for (int i = 0; i < chaseList.Length; i++)
                {
                    var chase = chaseList[i];
                    str += chase.xAxis.ToString("f1") + "," + chase.zAxis.ToString("f1") + " ";
                }
                Debug.LogError(str);
            }
        }
    }

    public void CheckNeedGenerateChasePathListAndRefresh(MarchEntity target)
    {
        var chaseList = GenerateChasePathList(target);
        if (chaseList != null)
        {
            var serverInfo = RtsServerInfo;
            serverInfo.lastFrameTime = TimeUtils.GetServerTimeMs();
            serverInfo.coordinate = chaseList[0];
            serverInfo.pathList = chaseList;
            MarchManager.UpdateTroop(MarchInfo.MarchIndex,serverInfo);
        }
    }

    private Coordinate[] GenerateChasePathList(MarchEntity target)
    {
        var serverData = target.RtsServerInfo;
        if (serverData.pathList == null || serverData.pathList.Length == 0 || !IsMoving())
        {

            //首先先算出对方1秒后所在的位置
            var segment = target.MarchInfo.Segment;
            var clientPosition = target.Position;

            if (Vector3.Distance(Position, clientPosition) > 0.8)
            {
                var moveDistance = target.MarchInfo.Speed;
                Vector3 latePosition;
                if (math.distance(clientPosition, segment.endPosition) < moveDistance)
                {
                    latePosition = segment.endPosition;
                }
                else
                {
                    latePosition = clientPosition + ((Vector3)segment.direction).normalized * moveDistance;
                }
                //计算出自己应该在的攻击位
                var dir = (Position - latePosition).normalized;
                var selfLatePosition = latePosition + dir * 0.7f;
                if (Vector3.Distance(selfLatePosition, target.Position) < Vector3.Distance(Position, target.Position))
                {
                    var newPathList = new Coordinate[2];
                    newPathList[0] = new Coordinate
                    {
                        xAxis = Position.x,
                        zAxis = Position.z
                    };
                    newPathList[1] = new Coordinate
                    {
                        xAxis = selfLatePosition.x,
                        zAxis = selfLatePosition.z,
                    };
                    serverData.pathList = newPathList;

                    //Debug.LogError(Tid+"模拟了追击");
                    return newPathList;
                }
            }

        }
        return null;
    }
    [BlackList]
    public void ForceSetPosition()
    {
        _marchSquare?.SetPosition(MarchInfo.Position,true);
        if (Hud != null)
        {
            Hud.UpdateFollowPos();
            Hud.MarchHudLod0?.SetNickNamePosition();
        }
    }
    public void ForceSetPosition(Vector3 position)
    {
        _marchSquare?.SetPosition(position, true);
        if (Hud != null)
        {
            Hud.MarchHudLod0?.SetNickNamePosition();
        }

    }

    public void ShowDebug()
    {
        string log = string.Format("部队{0}最近一次服务器数据：", Tid);
        log = log + "\n";
        if (ClientMarchType == EClientMarchType.March)
        {
            log = log + BattleUtils.ServerDataToString(RtsServerInfo);
        }
        Debug.LogError(log);
        log = string.Format("部队{0}客户端数据：", Tid);
        log = log + "\n";
        log += BattleUtils.ObjectToString(MarchInfo,"MarchInfo",0,2);
        Debug.LogError(log);

        var reporter = GameObject.FindObjectOfType<Reporter>();
        reporter.ShowLog = false;
        reporter.ShowWarning = false;
        reporter.ShowError = true;
        reporter.Show();
    }

    public void ForceShowCommanderHead(bool isShow,bool isBattleStyle)
    {
        Hud?.ForceShowSelectedUI(isShow, isBattleStyle);
    }

    public void ManualUpdateSelectedHud()
    {
        if (Hud is MarchHud marchHud)
        {
            marchHud.ManualUpdateCommanderInfo();
        }
    }

    public void ManualUpdateBattleHud()
    {
        if (Hud is MarchHud marchHud)
        {
            marchHud.UpdateCommanderBattle();
        }
    }

    [BlackList]
    public bool isBesiege = false;
    
    public bool IsReadyToRemove()
    {
        if (MarchInfo == null)
        {
            return true;
        }
        if (MarchInfo.MarchType == MarchType.DIE_5)
        {
            return true;
        }

        if (MarchInfo.MarchStatus == MarchStatus.REMOVE_4)
        {
            return true;
        }

        if (isBeforeDispose)
        {
            return true;
        }

        return false;
    }


    /// <summary>
    /// 检查是否是自己的部队
    /// </summary>
    /// <returns></returns>
    public bool CheckIsSelfMarch()
    {
        if(this.Team == (int)MarchTeam.Self)
        {
            return true;
        }
        return false;
    }

    public void SetNickName(string nickName)
    {
        if(Hud != null)
        {
            Hud.SetNickName(nickName);
        }
    }

    public void SetNickNameWithColor(string nickName, bool usOrEnemy)
    {
        if (Hud != null)
        {
            Hud.SetNickName(nickName);
            if (!usOrEnemy)
            {
                Hud.MarchHudLod0.PlayerNameText.color = MarchHelper.BattleDirectionColor[1];
                Hud.MarchHudLod0.SetNickNameColor(MarchHelper.BattleDirectionColor[1]);
            }
        }
    }
    
    public void SetRenownName(string renownName, int quality)
    {
        if (Hud != null)
        {
            Hud.SetRenownName(renownName, quality);
        }
    }

    public void SetKillTip(int killNum, string killTip)
    {
        if (Hud is MarchHud marchHud)
        {
            marchHud.SetKillTip(killNum, killTip);
        }
    }

    public void SetIsFakeParent()
    {
        if (!isFakeParent)
        {
            isFakeParent = true;
            childEntities = new List<MarchEntity>();
        }
        Hud?.Hide();
    }

    public List<MarchEntity> GetFakeChildEntities()
    {
        return childEntities;
    }

    public void AddFakeChild(MarchEntity child)
    {
        if (childEntities == null)
        {
            return;
        }

        for (int i = 0; i < childEntities.Count; i++)
        {
            if (childEntities[i] == child)
            {
                return;
            }
        }
        childEntities.Add(child);
    }

    public void PlaySkillAnimation(string animation)
    {
        _marchSquare?.PlaySkillAnimation(animation);
    }

    public void SetAttackAnimationSpeed(float animationSpeed,float speedTime)
    {
        _marchSquare?.SetAttackAnimationSpeed(animationSpeed, speedTime);
    }

    public void UpdateMonsterColliderEnabled(int lodLevel)
    {
        var touchable = Visible && lodLevel < WorldEntry.MaxShowMarchLodLevel && MarchInfo.MarchStatus != MarchStatus.REMOVE_4;
        SetTouchable(touchable);
    }

    public void OnHeroChanged()
    {
        Hud?.SwitchRageHero();
    }

    #region rts数据初次变更

    public void CheckRtsServerInfoChanged()
    {
        if (!IsInBattle && RtsServerInfo.curHeroIdx >= 0)
        {
            CurRageHeroIdx = RtsServerInfo.curHeroIdx;
        }
    }

    private void OnCurRageHeroIdxChange()
    {
        //Hud?.SetRageHeroChanged(true);
    }

    public void UpdateRageHerIdx(int heroIdx)
    {
        //Debug.LogError("设置当前收集进度英雄Id: " + heroIdx );
        CurRageHeroIdx = heroIdx;
    }
    #endregion

    #region 技能相关

    private void DisposeSkill()
    {
        if (m_CarSkillHit != null)
        {
            m_CarSkillHit?.Dispose();
            m_CarSkillHit = null;
        }
    }

    public void DisposeSkillOutSide()
    {
        if (m_CarSkillHit!=null)
        {
            m_CarSkillHit = null;
        }
    }

    /// <summary>
    /// 尝试延长豪车技能Buff的持续时间
    /// 本质上是类似于Buff的存在,但是实际上
    /// </summary>
    /// <returns></returns>
    public SkillHit GetCarSkill()
    {
        return m_CarSkillHit;
    }

    public void SetCarSkill(SkillHit skillHit)
    {
        m_CarSkillHit = skillHit;
    }

    public void SetMonsterRadius(int monsterType)
    {
        if (monsterType == 1)
        {
            Mono.SetColliderRadius(BattleUtils.ArmyScale);
        }
        else if (monsterType == 2)
        {
            Mono.SetColliderRadius(BattleUtils.ArmyScale);
        }
        else if(monsterType == 3)
        {
            Mono.SetColliderRadius(BattleUtils.ArmyScale);
        }
        else if(monsterType == 4)
        {
            Mono.SetColliderRadius(BattleUtils.ArmyScale);
        }
        else if(monsterType == 5)
        {
            Mono.SetColliderRadius(BattleUtils.ArmyScale);
        }
        else if(monsterType == 6)//走私车队
        {
            Mono.SetColliderRadius(0.6f);
        }
    }

    public void SetMarchHudLod1ExtraOffset(float extraOffset)
    {
        if (Hud is MarchHud marchHud)
        {
            marchHud.SetMarchHudLod1ExtraOffset(extraOffset);
        }
    }

    public void SetPlayerTitle()
    {
        if (Hud is MarchHud marchHud)
        {
            marchHud.SetPlayerTitle();
        }
    }


    #endregion

    public void SmuggleEntityUpdate()
    {
        _marchSquare?.UpdateSmuggleEffect();
    }

    public void FadeIn(float time) 
    {
        _marchSquare?.FadeIn(time);
    }

    public void FadeOut(float time,float delayTime = 0)
    {
        _marchSquare?.FadeOut(time, delayTime);
    }

    public void SetDelayRemoveTime(float time)
    {
        delayRemoveTime = time;
    }

    public void SetTruckCrushTime(float time,float duration,Vector3 crushDirection)
    {
        _marchSquare?.SetTruckCrushTime(time, duration, crushDirection);
    }

    public void SetIsTruckFighting(bool isFighting)
    {
        isTruckFighting = true;
        Hud?.SetIsTruckFighting(isFighting);
        _marchSquare?.SetClientInBattle(true,false,true);
    }

    public void SetIsTrainFighting(bool isFighting)
    {
        isTrainFighting = isFighting;
        Hud?.SetIsTrainFighting(isFighting);
        _marchSquare?.SetClientInBattle(true,false,true);
    }
    
    public void SetIsCanShowNewYearHud(bool value)
    {
        Hud?.SetIsCanShowNewYearHud(value);
    }

    public void SetNewYearHudVisible(bool value)
    {
        Hud?.SetNewYearHudVisible(value);
        
    }

    public void SetNewYearHudArgus(float cdTime, string iconPath, LuaFunction luaCallback)
    {
        Hud?.SetNewYearHudArgus(cdTime, iconPath, luaCallback);
    }

    public void SetNewYearHudIconPath(string iconPath)
    {
        Hud?.SetNewYearHudIconPath(iconPath);
    }
    
    //货车攻击方表现
    private bool isPlayingTruckAttacking = false;
    private TruckAttackerBehaviour truckAttackerBehaviour;
    public void StartPlayTruckAttacking(MarchEntity targetTruck,bool isAttackerWin,bool isWin,int battleIdx = 1,string res = "",float delayTime = 0)
    {
        truckAttackerBehaviour = new TruckAttackerBehaviour();
        truckAttackerBehaviour.Start(targetTruck,this,isAttackerWin,isWin,battleIdx, res, delayTime);
        isPlayingTruckAttacking = true;
        _marchSquare?.StartTruckAttacking();
    }

    private void UpdatePlayTruckAttacking()
    {
        truckAttackerBehaviour.Update();
        _marchSquare?.SetPosition(Position, true);
        _marchSquare?.UpdateTruckAttacking();
    }

    public bool IsTruckAttacking()
    {
        return isPlayingTruckAttacking;
    }

    public Vector3 GetTruckAttackerPosition()
    {
        if (truckAttackerBehaviour != null)
        {
            return truckAttackerBehaviour.getPosition();
        }
        else if (trainDefenceBehaviour != null)
        {
            return trainDefenceBehaviour.position;
        }
        else
        {
            return GlobalValue.INVISIBLE_POSITION;
        }
    }
    
    public Vector3 GetTruckAttackerForward()
    {
        if (truckAttackerBehaviour != null)
        {
            return truckAttackerBehaviour.forward;
        }
        else
        {
            return Vector3.forward;
        }
    }

    //货车攻击方表现
    private bool isPlayingTrainDefending = false;
    private TrainDefenceBehaviour trainDefenceBehaviour;
    public void StartPlayTrainDefending(MarchEntity defence,MarchEntity train,int battleIdx, float delayTime = 0)
    {
        trainDefenceBehaviour = new TrainDefenceBehaviour();
        trainDefenceBehaviour.Start(defence,train,battleIdx, delayTime);
        isPlayingTrainDefending = true;
    }
    
    private void UpdatePlayTrainDefending()
    {
        trainDefenceBehaviour?.Update();
    }
    
    public void SetIsPveBattleWin(bool isPveBattleWin)
    {
        this.isPveBattleWin = isPveBattleWin;
    }
    
    public bool isPveBattleWin = false;
    
    [BlackList]
    public bool isPortraitRotated = false;

    public bool isTruckAttackerMarch()
    {
        return ClientCreateMarch == 1;
    }
    
    public bool isTrainAttackerMarch()
    {
        return ClientCreateMarch == 2;
    }

    public bool isTrainDefenceMarch()
    {
        return ClientCreateMarch == 3;
    }


    public bool isClientCreateMarch()
    {
        return ClientCreateMarch > 0;
    }

    public bool isTroopWorldRight()
    {
        return RtsServerInfo.troopWorldId <= 0 || RtsServerInfo.troopWorldId == MarchManager.Instance.GetSandBoxServerId();
    }
}
